﻿using SCS.Common.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace SCS.DAL
{
    public class Repository<T> : IRepository<T>, IDisposable where T : class
    {
        protected SCSContext DBContext { get; set; }
        protected DbSet<T> DBSet { get; set; }
        public Repository(SCSContext dbContext)
        {
            if (dbContext == null)
            {
                throw new ArgumentNullException("dbContext");
            }
            else
            {
                DBContext = dbContext;
                DBSet = dbContext.Set<T>();
            }
        }
        /// <summary>
        /// Get Funciton
        /// </summary>
        /// <param name="predicate">search condition</param>
        /// <returns>T Class</returns>
        public IEnumerable<T> Get(Expression<Func<T, bool>> predicate)
        {
            return DBSet.Where(predicate).ToList();
        }
        public T First(Expression<Func<T, bool>> predicate)
        {
            return DBSet.Where(predicate).FirstOrDefault();
        }

        /// <summary>
        /// Get all of class T
        /// </summary>
        /// <returns>List T Class</returns>
        public IEnumerable<T> GetAll()
        {
            return DBSet.ToList();
        }

        /// <summary>
        /// Get all and order of class T
        /// </summary>
        /// <param name="keySelector">key to order</param>
        /// <returns>List of T</returns>
        public IEnumerable<T> GetAllOrderBy(Func<T, object> keySelector)
        {
            return DBSet.OrderBy(keySelector).ToList();
        }


        /// <summary>
        /// Get all and order by Descending of class T
        /// </summary>
        /// <param name="keySelector">key to order</param>
        /// <returns>List of T</returns>
        public IEnumerable<T> GetAllOrderByDescending(Func<T, object> keySelector)
        {
            return DBSet.OrderByDescending(keySelector).ToList();
        }

        /// <summary>
        /// Add Entity to DB Context
        /// </summary>
        /// <param name="entity">Entity</param>
        public void Add(T entity)
        {
            DBSet.Add(entity);
        }

        /// <summary>
        /// Update Entity to DB Context
        /// </summary>
        /// <param name="entity">Entity</param>
        public void Update(T entity)
        {
            DBContext.Entry(entity).State = EntityState.Modified;
        }

        /// <summary>
        /// Delete Entity to DB Context
        /// </summary>
        /// <param name="entity">Entity</param>
        public void Delete(T entity)
        {
            DBSet.Remove(entity);
        }

        /// <summary>
        /// Check Exist of a entity
        /// </summary>
        /// <param name="predicate">condition</param>
        /// <returns>True or False</returns>
        public bool CheckExist(Expression<Func<T, bool>> predicate)
        {
            if (DBSet.Where(predicate).Count() > 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// Dispose class
        /// </summary>
        public void Dispose()
        {
            if (DBContext != null)
            {
                DBContext.Dispose();
            }
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Find School Year
        /// </summary>
        /// <param name="id">id of schoolyear</param>
        /// <returns>SchoolYear Class</returns>
        public SchoolYear Find(int id)
        {
            return DBContext.SchoolYears.Find(id);
        }

        /// <summary>
        /// Return all SchoolYear
        /// </summary>
        /// <returns>List all school year</returns>
        public IQueryable<SchoolYear> All()
        {
            return DBContext.SchoolYears;
        }
    }
}